package org.molamil.acto.types {
	import org.molamil.acto.core.parsers.ParserError;
	
	/**
	 * Type parser expecting the value passed when <code>parse()</code> to 
	 * be "uint compatible". These values can e.g. be "100", "5", 
	 * "0xFF0000", etc.
	 * 
	 * <p>Note that unlike the <code>uint()</code> casting <code>parse()</code> 
	 * will fail if value is empty, if there are decimals or if a negative
	 * number is passed.</p>
	 * 
	 * @example The following code will parse "28" into <code>28</code>
	 * and will trace "HOLLY COW, I parsed a uint!!!":
	 * <listing version="3.0" >
	 * var parser:AbstractTypeParser = new UintTypeParser();
	 * var n:uint = parser.parse("28");
	 * if (n == 28)
	 *    trace("HOLLY COW, I parsed a uint!!!");
	 * </listing>
	 * 
	 * @author Jorge Hernandez
	 */
	public class UintTypeParser extends AbstractTypeParser {
		
		
		// CONSTANTS
		
		/**
		 * @inheritDoc
		 */
		public static const PRIORITY:uint = 200;
		
		/**
		 * @inheritDoc
		 */
		public static const TYPE:Class = int;
		
		
		// PROTECTED METHODS
		
		/**
		 * Returns the unsigned integer representation of the passed value, or throws
		 * an <code>Error</code> if value does not contain any representation 
		 * that can be parsed into a <code>uint</code>
		 * 
		 * <p>Note that unlike the <code>uint()</code> casting <code>parse()</code> 
	 	 * will fail if value is empty, if there are decimals or if a negative
	 	 * number is passed.</p>
		 * 
		 * <p>The following strings will parse into a uint</p>
		 * <ul>
		 * 	<li>"100" will parse into <code>100</code></li>
		 * 	<li>"1" will parse into <code>1</code></li>
		 * 	<li>"0x100" will parse into <code>256</code></li>
		 * </ul>
		 * 
		 * @param value <code>String</code> value to test
		 * @return Unsigned integer representation of the value passed
		 * @throws org.molamil.acto.core.errors.ParserError The value can't
		 * 	be converted to a <code>uint</code>
		 */
		override protected function doParse(value:String):* {
			
			if (value == null)
				throw new ParserError("ERROR: value is null and cannot be parsed " +
					"into a uint");
			
			var n:uint = uint(value);
			var nv:Number = Number(value);
			
			if (value == "")
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a uint (value is empty)");
					
			if (value.indexOf(".") != -1)
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a uint (value contains decimals)");
					
			if (isNaN(nv))
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a uint");
					
			if (nv > uint.MAX_VALUE)
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a uint (too big)");
					
			if (nv < uint.MIN_VALUE)
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a uint (too small)");
			
			if (n == 0 && nv != 0)
				throw new ParserError("ERROR: '" + value + "' cannot be parsed " +
					"into a uint");
			
			return n;
			
		}
		
		
	}
	
}
